//
//  LinphoneDelegate.swift
//  linphone_flutter
//
//  Created by alexcai on 2022/9/1.
//

import Foundation
import linphonesw
import Flutter

class LinphoneDelegate:NSObject,CoreDelegate, FlutterStreamHandler{
    
    var channel:FlutterEventChannel?
    var eventSink:FlutterEventSink?
    var flutterViewController:FlutterViewController? = nil
    
    init(binaryMessenger: FlutterBinaryMessenger){
        super.init()
        self.channel = FlutterEventChannel(name:"linphone_flutter/core", binaryMessenger: binaryMessenger)
        self.channel?.setStreamHandler(self)
    }
    
    func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
        self.eventSink = events
        return nil
    }
    
    func onCancel(withArguments arguments: Any?) -> FlutterError? {
        return nil
    }
    
    func onAccountRegistrationStateChanged (core: Core, account: Account, state: RegistrationState, message: String){
        if(nil == self.eventSink){
            return
        }
        // If account has been configured correctly, we will go through Progress and Ok states
        // Otherwise, we will be Failed.
        NSLog("New registration state is \(state) for user id \( String(describing: account.params?.identityAddress?.asString()))\n")
        var dic = [String : Any]()
        dic["type"] = "connected"
        if (state == .Ok) {
            dic["result"] = true
            self.eventSink!(dic)
        } else if (state == .Cleared) {
            dic["result"] = false
            self.eventSink!(dic)
        }
        
    }
    
    func onCallStateChanged(core: Core, call: Call, state: Call.State, message: String){
        if(nil == self.eventSink){
            return
        }
        var dic = [String : Any]()
        dic["type"] = "CallState"
        if (state == .IncomingReceived) { // When a call is received
            dic["result"] = "IncomingReceived"
            self.eventSink!(dic)
        } else if (state == .Connected) { // When a call is over
            dic["result"] =  "Connected"
            self.eventSink!(dic)
        } else if (state == .Released) { // When a call is over
            dic["result"] =  "Released"
            self.eventSink!(dic)
        }else if (state == .OutgoingInit) {
            dic["result"] =  "OutgoingInit"
            self.eventSink!(dic)
        }else if (state == .OutgoingProgress) {
            dic["result"] =  "OutgoingProgress"
            self.eventSink!(dic)
        }else if (state == .OutgoingRinging) {
            dic["result"] =  "OutgoingRinging"
            self.eventSink!(dic)
        } else if (state == .StreamsRunning) {
            dic["result"] =  "StreamsRunning"
            self.eventSink!(dic)
        } else if (state == .Paused) {
            dic["result"] =  "Paused"
            self.eventSink!(dic)
        } else if (state == .PausedByRemote) {
            dic["result"] =  "PausedByRemote"
            self.eventSink!(dic)
        } else if (state == .Updating) {
            dic["result"] =  "Updating"
            self.eventSink!(dic)
        } else if (state == .UpdatedByRemote) {
            dic["result"] =  "UpdatedByRemote"
            self.eventSink!(dic)
        } else if (state == .Released) {
            dic["result"] =  "Released"
            self.eventSink!(dic)
        } else if (state == .Error) {
            dic["result"] =  "Error"
            self.eventSink!(dic)
        }
    }
    
    func onAudioDeviceChanged (core: Core, device: AudioDevice) {
        // This callback will be triggered when a successful audio device has been changed
    }
    
    func onAudioDevicesListUpdated (core: Core) {
        // This callback will be triggered when the available devices list has changed,
        // for example after a bluetooth headset has been connected/disconnected.
    }
    
}
